package com.leinao.media.factory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.leinao.media.client.MediaClient;
import com.leinao.media.common.Result;
import com.leinao.media.factory.annotation.ServiceMethod;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

/**
 * 服务执行类
 *
 * @author zhangyu
 */
public class ServiceHandler<T> implements InvocationHandler {

    private final Class<T> clazz;
    private final MediaClient mediaClient;

    public ServiceHandler(Class<T> clazz, MediaClient mediaClient) {
        this.clazz = clazz;
        this.mediaClient = mediaClient;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ServiceMethod mark = method.getAnnotation(ServiceMethod.class);
        if (mark == null) {
            Method localMethod = this.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
            return localMethod.invoke(this, args);
        } else {
            Type type = method.getGenericReturnType();
            Object req = null;
            if (args != null && args.length > 0) {
                req = args[0];
            }
            return this.exec(mark.value(), req, type);
        }
    }

    @Override
    public boolean equals(Object obj) {
        return this.clazz.equals(obj);
    }

    @Override
    public int hashCode() {
        return this.clazz.hashCode();
    }

    @Override
    public String toString() {
        return this.clazz.toString();
    }

    protected <R, T> Result<R> exec(String uri, T req, Type resultType) {
        String body = JSON.toJSONString(req);
        String resp = this.mediaClient.post(uri, body);
        return JSON.parseObject(resp, resultType, new Feature[0]);
    }
}
